"""
Models and base models for things that are publishable.
"""

import datetime
from django.db import models
from base import *
from object_types import *

_model_names = ["Resource", "Entity", "Contact"]
__all__ = _model_names + ["CONTACT_ROLES"]

CONTACT_ROLES = (("owner","Represents an owner of a resource."),
                 ("creator", "Created the resource."),
                 ("publisher", "Represents a publisher of a resource."),
                 ("contributor", "A general contributor to the creation of the resource."))

class Entity(MetadataObject):
    """
    A person or organization that could be a data creator, publisher,
    owner or contributor.

    Here's an example of how serialization/deserialization works:

    First, to JSON

    >>> e = Entity(name='Joe Wonderful', address='1 Happy Lane, Smileytowne, CA')
    >>> print e.to_json(indent=2)
    {
      "website": "", 
     "name": "Joe Wonderful", 
     "short_name": "", 
     "telephone": "", 
     "id": null, 
     "address": "1 Happy Lane, Smileytowne, CA", 
     "model": "Entity", 
     "email": ""
    }
    >>> 

    Now, from JSON (note that we keep creating a new entity)

    >>> js = '{"name": "Rick"}'
    >>> e = Entity()
    >>> e.from_json(js)
    >>> e.name
    u'Rick'
    >>> 

    And from a dictionary

    >>> d = {'name':'Rick', 'email':'example@example.edu'}
    >>> e = Entity()
    >>> e.from_dict(d)
    >>> e.email
    'example@example.edu'
    >>> e.name
    'Rick'

    Finally, both from_json and from_dict can preserve the primary keys of the object.

    >>> d = {'name':'Rick', 'email':'example@example.edu', 'id': 99}
    >>> e = Entity()
    >>> e.from_dict(d, preserve_ids=True)
    >>> e.id
    99
    """

    _collection_sets = []
    name = models.CharField(max_length=1024)
    short_name = models.SlugField(unique=True)
    address = models.TextField(blank=True)
    email = models.EmailField(blank=True)
    telephone = models.CharField(max_length=256, blank=True)
    website = models.URLField(blank=True)

    def __unicode__(self):
        return self.name

class Resource(MetadataObject):
    _collection_sets = []
    name = models.CharField(max_length=256)
    short_name = models.SlugField(blank=True)
    description = models.TextField(blank=True)
    referenceURL = models.URLField(blank=True)
    publisherDID = models.SlugField(blank=True)
    created = models.DateTimeField(editable=False,
                                   blank=True,
                                   default=datetime.datetime.now)
    updated = models.DateTimeField(null=True, blank=True, auto_now=True)
    status = models.CharField(max_length=1024, default='valid', blank=True)

    def __unicode__(self):
        return self.name

class Contact(MetadataObject):
    # A contact is an entity with a role.
    _collection_sets = []
    resource = models.ForeignKey(Resource)
    entity = models.ForeignKey(Entity, blank=True, null=True)
    role = models.CharField(max_length=256, 
                            choices=CONTACT_ROLES,
                            default='owner')
    _container_field = "resource_id"
    Resource._collection_sets.append('contact_set')

    def __unicode__(self):
        return self.resource.name + ': ' + self.role
